﻿

namespace LocalNas.Application.Module.PicHunter
{
    public class XrmnService : IPicHunterService, ITransient
    {
        private const string Root = "https://www.xrmnw.cc";

        public async Task<List<GetCoverListResult>> GetCoverList(GetTypesResult type, int page)
        {
            try
            {
                var url = Root + (page == 1 ? type.TypeUrl : $"{type.TypeUrl}index{page}.html");
                var web = new HtmlWeb();
                var doc = await web.LoadFromWebAsync(url);
                var cols = doc.DocumentNode.SelectNodes("/html/body/div[3]/div[2]/div/ul/li");
                var list = cols.Select(x => new GetCoverListResult
                {
                    Cover = Root + x.SelectSingleNode("a/img").Attributes["src"].Value,
                    Title = x.SelectSingleNode("a").Attributes["title"].Value,
                    Url = Root + x.SelectSingleNode("a").Attributes["href"].Value,
                }).ToList();
                return list;
            }
            catch (Exception)
            {
                await ReceiveMessage(new SendMessageData
                {
                    MessageType = MessageTypeEnum.日志,
                    Title = "错误",
                    Message = $"{type.TypeName}封面获取失败",
                });
                return null;
            }

        }

        public async Task GetAllPicture(GetCoverListResult request, string savePath, int totalCount)
        {
            var web = new HtmlWeb();
            HtmlDocument doc;
            try
            {
                doc = await web.LoadFromWebAsync(request.Url);
            }
            catch (Exception)
            {
                await ReceiveMessage(new SendMessageData
                {
                    MessageType = MessageTypeEnum.日志,
                    Title = "错误",
                    Message = $"{request.Title}详情获取失败",
                });
                return;
            }
            var pageNodes = doc.DocumentNode.SelectNodes("/html/body/div[3]/div/div/div[4]/div/div/a");
            if (pageNodes == null) return;
            var totalPage = int.Parse(pageNodes[pageNodes.Count - 2].InnerText);
            var index = 0;
            var path = Path.Combine(savePath, request.Title);
            if (!Directory.Exists(path))
            {
                try
                {
                    Directory.CreateDirectory(path);
                }
                catch (Exception)
                {
                    await ReceiveMessage(new SendMessageData
                    {
                        MessageType = MessageTypeEnum.日志,
                        Title = "错误",
                        Message = $"创建目录失败，请检查目录{path}",
                    });
                    return;
                }

            }


            for (int i = 0; i < totalPage; i++)
            {
                var url = i == 0 ? request.Url : request.Url.Replace(".html", $"_{i}.html");
                try
                {
                    doc = i == 0 ? doc : await web.LoadFromWebAsync(url);
                }
                catch (Exception)
                {
                    await ReceiveMessage(new SendMessageData
                    {
                        MessageType = MessageTypeEnum.日志,
                        Title = "错误",
                        Message = $"{request.Title}详情获取失败",
                    });
                    continue;
                }

                var imgNodes = doc.DocumentNode.SelectNodes("/html/body/div[3]/div/div/div[3]/div/p/img");

                foreach (var img in imgNodes)
                {
                    index += 1;
                    var fileName = $"{index:000}.jpg";
                    if (File.Exists(Path.Combine(path, fileName)))
                    {
                        //await ReceiveMessage(new SendMessageData
                        //{
                        //    MessageType = MessageTypeEnum.日志,
                        //    Title = "跳过",
                        //    Message = $"[{index}/{totalCount}]{request.Title}"
                        //});
                        await ReceiveMessage(new SendMessageData
                        {
                            Title = "跳过",
                            Message = $"[{index}/{totalCount}]{request.Title}",
                            MessageType = MessageTypeEnum.目录进度,
                            Data = new
                            {
                                Path = path,
                                Current = i,
                                Total = totalCount,
                                Proccess = i * 100 / totalCount
                            }
                        });
                        continue;
                    }
                    var src = Root + img.Attributes["src"].Value;
                    try
                    {
                        var stream = await src.GetAsStreamAsync();
                        using (var fileStream = File.Create(Path.Combine(path, fileName)))
                        {
                            await stream.Stream.CopyToAsync(fileStream);
                        }
                        await ReceiveMessage(new SendMessageData
                        { 
                            Title = "成功",
                            Message = $"[{index}/{totalCount}]{request.Title}",
                            MessageType = MessageTypeEnum.目录进度,
                            Data = new
                            {
                                Path = path,
                                Current = i,
                                Total = totalCount,
                                Proccess = i * 100 / totalCount
                            }
                        });
                    }
                    catch (Exception)
                    {
                        await ReceiveMessage(new SendMessageData
                        {
                            MessageType = MessageTypeEnum.日志,
                            Title = "错误",
                            Message = $"[{index}/{totalCount}]{request.Title}"
                        });
                        continue;
                    }
                }
            }
        }

        public async Task<List<GetTypesResult>> GetTypes()
        {
            try
            {
                var web = new HtmlWeb();
                var doc = await web.LoadFromWebAsync(Root);
                var typeNodes = doc.DocumentNode.SelectNodes("//*[@id=\"menu-item-205\"]/ul/li/a");
                var types = typeNodes.Select(x => new GetTypesResult
                {
                    TypeName = x.InnerText,
                    TypeUrl = x.Attributes["href"].Value
                }).ToList();
                return types;
            }
            catch (Exception)
            {
                await ReceiveMessage(new SendMessageData
                {
                    MessageType = MessageTypeEnum.日志,
                    Title = "错误",
                    Message = "分类获取失败",
                });
                return null;
            }

        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public async Task<int> ListTotalPage(GetTypesResult type)
        {
            try
            {
                var web = new HtmlWeb();
                var doc = await web.LoadFromWebAsync($"{Root}{type.TypeUrl}", new NetworkCredential { });
                var pageNode = doc.DocumentNode.SelectSingleNode("/html/body/div[3]/div[2]/div/div/span[2]/input");
                var totalPage = new Regex("(?<=this\\.value<=).*?(?=&)").Match(pageNode.Attributes["onkeydown"].Value).Value;
                return int.Parse(totalPage);
            }
            catch (Exception)
            {
                await ReceiveMessage(new SendMessageData
                {
                    MessageType = MessageTypeEnum.日志,
                    Title = "错误",
                    Message = "图片页码获取失败",
                });
            }
            return 1;
        }

        private async Task ReceiveMessage(SendMessageData data)
        {
            var hubContext = App.GetService<IHubContext<LogHub, ILogClient>>();
            await hubContext.Clients.All.ReceiveMessage(data);
            Console.WriteLine($"{data.Time:yyyyy/MM/dd HH:mm:ss.fff} =>【{data.Title}】{data.Message}");
        }
    }
}
